// 定义Promise构造函数
function Promise(excutor){
    this.PromiseState = "pending";
    this.PromiseResult = undefined;
    this.callbacks = []; // 用于存放待执行函数的属性

    // 声明成功处理内函数
    const success = (value) => {
        // 判断状态PromiseState是否已经不是pending，则退出
        if(this.PromiseState != "pending") return;
        this.PromiseState = "fulfilled";
        this.PromiseResult = value;
        // 执行callbacks属性里面保存下来没有执行的回调（异步导致）
        this.callbacks.forEach(item => {
            // 执行成功的回调方法ok
            item.ok();
        });
    }
    const error = (reason) => {
        // 判断状态PromiseState是否已经不是pending，则退出
        if(this.PromiseState != "pending") return;
        this.PromiseState = "rejected";
        this.PromiseResult = reason;
        // 执行callbacks属性里面保存下来没有执行的回调（异步导致）
        this.callbacks.forEach(item => {
            // 执行失败的回调方法ng
            item.ng();
        });
    } 
    try {
        // 执行excutor函数，要求传递两个函数类型参数
        excutor(success, error);
    } catch (e) {
        error(e);
    }
    
}

// 在Promise构造函数的原型上添加then方法
Promise.prototype.then = function(onResolved, onRejected){
    return new Promise((resolve, reject) => {
        // 声明一个函数 『handle 处理的意思』
        let handle = (type) => {
            try{
                let res = type(this.PromiseResult);
                // 判断res结果是否是一个Promise
                if(res instanceof Promise){
                    // 将当前res的promise状态添加到新的Promise
                    res.then(v => {
                        resolve(v);
                    },r => {
                        reject(r);
                    });
                } else {
                    // 若返回值不是Promise对象，就直接返回一个成功的，值为返回值的promise
                    resolve(res);
                }
            }catch(e){
                reject(e);
            }
        }
        // 判断PromiseState状态值来执行对应的参数函数
        if(this.PromiseState === "fulfilled"){
            handle(onResolved);
        }
        if(this.PromiseState === "rejected"){
            handle(onRejected);
        }
        // 判断PromiseState状态值为pending时，先将两个参数函数收取起来，等待改变状态是再次执行
        if(this.PromiseState === "pending"){
            // 将当前待调用的回调函数保存起来
            this.callbacks.push({
                // 状态成功时调用方法
                ok:function(value){
                    handle(onResolved);
                },
                // 状态失败是调用方法
                ng:function(reason){
                    handle(onRejected);
                }
            })
        }
        
    });
    
} 

// 在Promise构造函数的原型上添加catch方法
Promise.prototype.catch = function(onRejected){
    return this.then(undefined,onRejected);
} 

// 为Promiset构造函数直接添加resolve方法（静态方法）
Promise.resolve = function(value){
    return new Promise((resolve,reject) => {
        // 判断value结果是否是一个Promise
        if(value instanceof Promise){
            // 将当前res的promise状态添加到新的Promise
            value.then(v => {
                resolve(v);
            },r => {
                reject(r);
            });
        }else{
            resolve(value);
        }
    })
}

// 为Promiset构造函数直接添加reject方法（静态方法）
Promise.reject = function(reason){
    return new Promise((resolve,reject) => {
        reject(reason);
    })
}

// 为Promiset构造函数直接添加 all 方法
Promise.all = function(promiseArr){
    // 声明一个数组
    let data = [];
    // 声明计数器
    //let count = 0;
    // 返回值 promise 对象
    return new Promise((resolve, reject) => {
        // 遍历
        promiseArr.forEach((item, index) => {
            // 调用 then 方法
            item.then(v=>{
                // 当所有的 promise 对象状态都为成功的时候, 
                // 才能调用 resolve 函数, 并设置成功的结果值
                // data.push(v);
                data[index] = v; // data[2] = 'Yeah'
                // 成功一个自增
               // count++;
                // 判断长度是否已满
                if((index+1) === promiseArr.length){
                    resolve(data);
                }
            }, r=>{
                //如果当前 promise 失败, 则修改 all 返回 promise 状态为失败
                reject(r);
            })
        })
    });
} 

//添加 race 方法
Promise.race = function(promiseArr){
    return new Promise((resolve, reject) => {
        //遍历数组
        promiseArr.forEach(item => {
            item.then(v => {
                resolve(v);
            }, r => {
                reject(r);
            })
        });
    })
}
